package com.kehutong.admin.controler;

import java.util.Collections;
import java.util.List;

import org.coraframework.authz.HasPermission;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONArray;
import org.coraframework.json.JSONObject;
import org.coraframework.mvc.ActionResult;
import org.coraframework.mvc.MvcAction;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.http.result.Result;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.util.Objects;

import com.kehutong.admin.entity.Area;
import com.kehutong.admin.enums.Level;
import com.kehutong.admin.util.TreeUtil;
import com.kehutong.admin.util.UserUtils;

@MvcAction
@ReqMapping("/admin/sys/area")
public class AreaController {

    @Inject
    private JdbcSession jdbcSession;

    @ReqMapping(value = "/getChild")
    public Object getChild(String pid) {
    	final List<Area> areaList = jdbcSession.findArray(Area.class)
    		.eq("parent_id", pid)
    		.eq("deleted", false)
    		.exe();
       
        return Result.success(areaList);
    }

    @HasPermission("sys:area:view")
    @ReqMapping(value = "/listArea")
    public Object listArea(String parent_id) throws Exception {
    	final List<Area> areaList = jdbcSession.findArray(Area.class)
				.eq("parent_id", parent_id)
				.eq("deleted", false)
				.exe();

    	return toJSONArray(areaList);
    }
    
    @HasPermission("sys:area:view")
    @ReqMapping("/childTree")
    public Object list(JSONObject jsonObject) throws Exception {
    	Area root = UserUtils.getAreaTree(true);
    
    	String parentid = jsonObject.getString("parentId");
    	final List<Area> childList = root.getChildList();
    	for (Area area : childList) {
    		if (area.getId().equals(parentid)) {
    			return  Result.success(area);
    		}
    	}
    	
        return Result.success(Collections.emptyList());
    }
    
    @ReqMapping(value = "/tree")
    public ActionResult<String> listAsTree(JSONObject jsonObject) throws Exception {
    	Area root = UserUtils.getAreaTree(true);
       
        return Result.success(root);
    }
    
    @HasPermission("sys:area:view")
    @ReqMapping("/get")
    public ActionResult<String> getById(JSONObject jsonObject) {
    	Area area = jdbcSession.findById(Area.class, jsonObject.getString("id"));
    	
    	if (area != null && Objects.nonEmpty(area.getParent_id())) {
    		area.setParent(Pool.get(Area.class, area.getParent_id()));
    	}
		
    	return Result.success(area);
    }


    @HasPermission("sys:area:edit")
    @ReqMapping("/save")
    public ActionResult<String> save(JSONObject jsonObject) {
		Area area = Pool.newInstance(Area.class);
		setProperty(area, jsonObject);
		if (area.getType() == null) {
			return Result.error(1100, "地域级别不能低于区、县级别");
		}
		
		jdbcSession.insert(area);
		
        return Result.success();
    }

    @HasPermission("sys:area:edit")
    @ReqMapping("/update")
    public ActionResult<String> update(JSONObject jsonObject) {
		Area area = Pool.get(Area.class, jsonObject.getString("id"));
		setProperty(area, jsonObject);
		
		jdbcSession.updateById(area);
		
		return Result.success();
		
    }

    @HasPermission("sys:area:edit")
    @ReqMapping("/delete")
    public Object deleteById(Area area) {
    	area.setDeleted(true);
		jdbcSession.updateById(area);
		
        return Result.success();
    }
    
	private void setProperty(Area item, JSONObject jsonObject) {
		item.setName(jsonObject.getString("name"));
		item.setCode(jsonObject.getString("code"));
		item.setDeleted(false);
		Area parent = Pool.get(Area.class, jsonObject.getString("parent_id"));
		if (Objects.nonNull(parent)) {
			item.setParent_id(parent.getId());
			item.setParent_ids(TreeUtil.getParentIds(item));
			while (item.getParent_ids().remove(null));
		}
		item.setType(parent.getType().next());
	}

	private JSONArray toJSONArray(List<Area> areaList) {
    	JSONArray jsonArray = new JSONArray(areaList.size());
		areaList.forEach(area->{
			JSONObject json = new JSONObject();
			json.put("id", area.getId());
			json.put("name", area.getName());
			json.put("code", area.getCode());
			json.put("hasChildren", area.getType() != Level.AREA);
			jsonArray.add(json);
		});
    	return jsonArray;
	}
}
